package controller;

import java.awt.Cursor;
import java.awt.Point;
import java.awt.event.KeyEvent;

import model.DefaultModel;
import model.PointControl;

import vue.AireDePoint;

public enum StateAireDePoint implements InterfaceStateAireDePoint {
	UP_NO_COURBE {
		@Override
		public InterfaceStateAireDePoint keyPress(int key) {
			// ne rien faire
			return this;
		}

		@Override
		public InterfaceStateAireDePoint mouseDragged(Point p) {
			// ne rien faire //impossible
			return this;
		}

		@Override
		public InterfaceStateAireDePoint mouseMoved(Point p) {
			if (model.isOverPoint(p))
				aireDePoint.setCursor(new Cursor(Cursor.HAND_CURSOR));
			else
				aireDePoint.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
			return this;
		}

		@Override
		public InterfaceStateAireDePoint mousePressed(Point p, int button) {
			if (model.isOverPoint(p)) {
				model.select(p);
				point = p;
				return DOWN_NO_COURBE;
			} else {
				model.add(p);
				point = p;
				return DOWN_COURBE;
			}
		}

		@Override
		public InterfaceStateAireDePoint mouseReleased(Point p) {
			// ne rien faire //impossible
			return this;

		}
	},
	DOWN_COURBE {
		@Override
		public InterfaceStateAireDePoint keyPress(int key) {
			if (key == KeyEvent.VK_ESCAPE) {
				model.finishCourbe();
				return UP_NO_COURBE;
			}
			return this;
		}

		@Override
		public InterfaceStateAireDePoint mouseDragged(Point p) {
			if (point.distance(p) < behaviourAireDePoint.MARGE_CLIC) {
				// selection en cours
				return this;
			} else {
				model.setTangente(p);
				model.displayTengente(true);
				return DOWN_COURBE_TANGENTE;
			}
		}

		@Override
		public InterfaceStateAireDePoint mouseMoved(Point p) {
			// ne rien faire //impossible
			return this;
		}

		@Override
		public InterfaceStateAireDePoint mousePressed(Point p, int button) {
			// ne rien faire //impossible
			return this;
		}

		@Override
		public InterfaceStateAireDePoint mouseReleased(Point p) {
			System.out.println("Passage à UP_COURBE");
			return UP_COURBE;
		}
	},
	UP_COURBE {
		@Override
		public InterfaceStateAireDePoint keyPress(int key) {
			return DOWN_COURBE.keyPress(key);
		}

		@Override
		public InterfaceStateAireDePoint mouseDragged(Point p) {
			// ne rien faire //impossible
			return this;
		}

		@Override
		public InterfaceStateAireDePoint mouseMoved(Point p) {
			if (model.isOverPoint(p))
				aireDePoint.setCursor(new Cursor(Cursor.HAND_CURSOR));
			else
				aireDePoint.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
			return this;
		}

		@Override
		public InterfaceStateAireDePoint mousePressed(Point p, int button) {

			if (model.isOverPoint(p)) {
				model.select(p);
				System.out.println("Passage à DOWN_COURBE_POINT");
				return DOWN_COURBE_POINT;
			} else {
				model.add(p);
				point = p;
				return DOWN_COURBE;
			}
		}

		@Override
		public InterfaceStateAireDePoint mouseReleased(Point p) {
			// ne rien faire //impossible
			return this;

		}
	},
	DOWN_COURBE_TANGENTE {
		@Override
		public InterfaceStateAireDePoint keyPress(int key) {
			return DOWN_COURBE.keyPress(key);
		}

		@Override
		public InterfaceStateAireDePoint mouseDragged(Point p) {
			model.setTangente(p);
			return this;
		}

		@Override
		public InterfaceStateAireDePoint mouseMoved(Point p) {
			// ne rien faire //impossible
			return this;
		}

		@Override
		public InterfaceStateAireDePoint mousePressed(Point p, int button) {
			// ne rien faire //impossible
			return this;
		}

		@Override
		public InterfaceStateAireDePoint mouseReleased(Point p) {
			model.setTangente(p);
			model.displayTengente(false);
			return UP_COURBE;

		}
	},
	DOWN_COURBE_POINT {
		@Override
		public InterfaceStateAireDePoint keyPress(int key) {
			return DOWN_COURBE.keyPress(key);
		}

		@Override
		public InterfaceStateAireDePoint mouseDragged(Point p) {
			model.moveCurrentPoint(p);
			return this;
		}

		@Override
		public InterfaceStateAireDePoint mouseMoved(Point p) {
			// ne rien faire //impossible
			return this;
		}

		@Override
		public InterfaceStateAireDePoint mousePressed(Point p, int button) {
			// ne rien faire //impossible
			return this;
		}

		@Override
		public InterfaceStateAireDePoint mouseReleased(Point p) {
			model.moveCurrentPoint(p);
			return UP_COURBE;

		}
	},
	DOWN_NO_COURBE {
		@Override
		public InterfaceStateAireDePoint keyPress(int key) {
			return DOWN_COURBE.keyPress(key);
		}

		@Override
		public InterfaceStateAireDePoint mouseDragged(Point p) {
			if (point.distance(p) > behaviourAireDePoint.MARGE_CLIC) {
				model.moveCurrentPoint(p);
				return DOWN_NO_COURBE_MOVE;
			} else {
				return this;
			}

		}

		@Override
		public InterfaceStateAireDePoint mouseMoved(Point p) {
			// ne rien faire //impossible
			return this;
		}

		@Override
		public InterfaceStateAireDePoint mousePressed(Point p, int button) {
			// ne rien faire //impossible
			return this;
		}

		@Override
		public InterfaceStateAireDePoint mouseReleased(Point p) {
			model.displayTengente(true);

			return UP_NO_COURBE_SELECT;

		}
	},
	DOWN_NO_COURBE_MOVE {
		@Override
		public InterfaceStateAireDePoint keyPress(int key) {
			return DOWN_COURBE.keyPress(key);
		}

		@Override
		public InterfaceStateAireDePoint mouseDragged(Point p) {
			model.moveCurrentPoint(p);
			return this;
		}

		@Override
		public InterfaceStateAireDePoint mouseMoved(Point p) {
			// ne rien faire //impossible
			return this;
		}

		@Override
		public InterfaceStateAireDePoint mousePressed(Point p, int button) {
			// ne rien faire //impossible
			return this;
		}

		@Override
		public InterfaceStateAireDePoint mouseReleased(Point p) {
			return UP_NO_COURBE_SELECT;

		}
	},
	UP_NO_COURBE_SELECT {
		@Override
		public InterfaceStateAireDePoint keyPress(int key) {
			return DOWN_COURBE.keyPress(key);
		}

		@Override
		public InterfaceStateAireDePoint mouseDragged(Point p) {
			// ne rien faire //impossible
			return this;
		}

		@Override
		public InterfaceStateAireDePoint mouseMoved(Point p) {
			if (model.isOverPoint(p) || model.isOverTangente(p))
				aireDePoint.setCursor(new Cursor(Cursor.HAND_CURSOR));
			else
				aireDePoint.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
			return this;
		}

		@Override
		public InterfaceStateAireDePoint mousePressed(Point p, int button) {
			if (model.isOverPoint(p)) {
				model.displayTengente(false);
				model.select(p);
				point = p;
				return DOWN_NO_COURBE;
			} else if (model.isOverTangente(p)) {
				return StateAireDePoint.DOWN_NO_COURBE_SELECT_TANGENTE;
			} else {
				model.displayTengente(false);
				model.add(p);
				point = p;
				return DOWN_COURBE;
			}
		}

		@Override
		public InterfaceStateAireDePoint mouseReleased(Point p) {
			// ne rien faire //impossible
			return this;

		}
	},
	DOWN_NO_COURBE_SELECT_TANGENTE {
		@Override
		public InterfaceStateAireDePoint keyPress(int key) {
			return DOWN_COURBE.keyPress(key);
		}

		@Override
		public InterfaceStateAireDePoint mouseDragged(Point p) {
			model.setTangente(p);
			return this;
		}

		@Override
		public InterfaceStateAireDePoint mouseMoved(Point p) {
			// ne rien faire //impossible
			return this;
		}

		@Override
		public InterfaceStateAireDePoint mousePressed(Point p, int button) {
			// ne rien faire //impossible
			return this;
		}

		@Override
		public InterfaceStateAireDePoint mouseReleased(Point p) {
			return UP_NO_COURBE_SELECT;

		}
	};

	private static Point point;
	private static DefaultModel model;
	private static AireDePoint aireDePoint;

	public static InterfaceStateAireDePoint init(DefaultModel model1,
			AireDePoint aireDePoint1) {
		model = model1;
		aireDePoint = aireDePoint1;
		return UP_NO_COURBE;
	}

}
